#include "stdafx.h"
#include "adaptorserver.h"
#include <sstream>

AdaptorServer::AdaptorServer(OrderLink *ol, MarketDataLink* ml, AdaptorDlgBase *dialog) {
	mSocketList.clear();
	mOrderLink = ol;
	mDialog = dialog;
	mMarketDataLink = ml;
	mConfig = Config::getInstance();
	mInstrumetList = new CommInstrumentList();
	mMarketDataLink->SetInstrumentList(mInstrumetList);
}


AdaptorServer::~AdaptorServer() {
}

void AdaptorServer::startServer() {
	mDialog->addMessage("Starting Server now");
	if( AfxSocketInit() == FALSE ) {
		mDialog->addMessage("Cannot init socket\n");
		return;
	}

	if (Create (1919) ==  FALSE) {
		mDialog->addMessage( "Cannot create socket on 1919\n" );
		return;
	}

	if( Listen() == FALSE ) {
		mDialog->addMessage("Cannot listen\n" );
		return;
	}

	mDialog->addMessage( "Server started\n" );

	loadAllInstruments();
}

void AdaptorServer::loadAllInstruments() {
	string instruments = mConfig->getValue("Instruments", "");
	mInstrumetList->LoadAllInstrument(instruments);
}

void AdaptorServer::OnAccept(int nErrorCode) {
	AdaptorSocket *socket = new AdaptorSocket (mOrderLink, this);
	Accept( *socket );
	mSocketList.push_back (socket);
	CSocket::OnAccept(nErrorCode);

	mDialog->addMessage("Client Accepted");
}

void AdaptorServer::clientClosed(AdaptorSocket *socket) {
	mDialog->addMessage("Client closed, removing the client from market subscription");
	mInstrumetList->RemoveMarketDataSubscriptionFromList(socket);
}

void AdaptorServer::clientLogin(AdaptorSocket *socket, const ZAdaptorLoginMessage *msg) {
	mDialog->addMessage("Client login succesful " + string(msg->zNameField.zVal));
	ZAdaptorLoginStatusMessage status;
	status.zErrorCodeField.zVal = ZAdaptorErrorCodeField::AllOk;
	char buf[ZAdaptorLoginStatusMessage::Length+1];
	int len;
	len = ZAdaptorLoginStatusMessage::set(buf, &status);
	socket->Send(buf, len);
}

void AdaptorServer::reqMarketData(AdaptorSocket *socket, const ZAdaptorMarketDataSubMessage *msg) {
	string instrumentID = string(msg->zSymbolField.zVal);
	CommInstrument *instr = mInstrumetList->GetInstrumentByID(instrumentID);
	ZAdaptorMarketDataSubStatusMessage status;
	char buf[ZAdaptorMarketDataSubStatusMessage::Length + 1];
	int len;
	status.zSymbolField.zVal = msg->zSymbolField.zVal;
	status.zFlagField.zVal = msg->zFlagField.zVal;
	bool toSub = (msg->zFlagField.zVal == ZAdaptorFlagField::On);

	if (instr) {
		if( toSub ) {
			// add the socket to the sub list 
			instr->AddSocketToSubscribeList(socket);
			mDialog->addMessage("Add socket to " + instrumentID + " market data subscription list");
		} else {
			instr->RemoveSocketFromSubscribeList(socket);
			mDialog->addMessage("Remove socket from " + instrumentID + " market data subscription list");
		}
		status.zErrorCodeField.zVal = ZAdaptorErrorCodeField::AllOk;
		status.zInstrumentIndexField.zVal = instr->Index;

	} else {
		// Instrument not found
		status.zErrorCodeField.zVal = ZAdaptorErrorCodeField::InstrumentNotFound;
		status.zInstrumentIndexField.zVal = -1;
		mDialog->addMessage("Cannot find instrument for " + instrumentID);
	}

	len = ZAdaptorMarketDataSubStatusMessage::set(buf, &status);
	socket->Send(buf, len);

	if(instr && instr->CanPublish && toSub) {
		instr->PubMarketDataBestLevelSnapshot();
		instr->PubMarketTradeSnapshot();
	}
}
